/**create by liuhua at 2020年7月27日 下午3:09:37**/
package com.star.aries.utils;

import java.time.Duration;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.Period;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.Date;

public class DateUtils {
  public static ZoneId zone = ZoneId.systemDefault();

  public static String formatTodayDateTime() {
    return formatDateTime(new Date(), "yyyy-MM-dd HH:mm:ss");
  }
  
  public static String formatDateTime(Date date) {
    return formatDateTime(date, "yyyy-MM-dd HH:mm:ss");
  }

  public static String formatDateTime(long milli) {
    return formatDateTime(Date.from(Instant.ofEpochMilli(milli)), "yyyy-MM-dd HH:mm:ss");
  }

  public static String formatDateTime(Date date, String pattern) {
    LocalDateTime ldt = LocalDateTime.ofInstant(date.toInstant(), zone);
    return ldt.format(DateTimeFormatter.ofPattern(pattern));
  }

  public static String formatDateTime(LocalDateTime localDateTime, String pattern) {
    return localDateTime.format(DateTimeFormatter.ofPattern(pattern));
  }

  public static Date toDateYmd(String date) {
    return toDate(date, "yyyy-MM-dd");
  }

  public static Date toDateYmdHms(String datetime) {
    return toDateTime(datetime, "yyyy-MM-dd HH:mm:ss");
  }

  public static Date toDateTime(String datetime, String pattern) {
    LocalDateTime dt = toLocalDateTime(datetime, pattern);
    return Date.from(dt.atZone(zone).toInstant());
  }

  public static Date toDate(String date, String pattern) {
    LocalDateTime dt = LocalDateTime.of(toLocalDate(date, pattern), LocalTime.of(0, 0));
    return Date.from(dt.atZone(zone).toInstant());
  }

  public static Date toDate(LocalDateTime localDateTime) {
    return Date.from(localDateTime.atZone(zone).toInstant());
  }

  public static LocalDateTime toLocalDateTime(long timestamp) {
    Instant instant = Instant.ofEpochMilli(timestamp);
    return LocalDateTime.ofInstant(instant, zone);
  }

  public static LocalDateTime toLocalDateTime(Date date) {
//    date.toInstant().atZone(zone).toLocalDateTime();
    return LocalDateTime.ofInstant(date.toInstant(), zone);
  }

  public static LocalDateTime toLocalDateTime(String datetime, String format) {
    return LocalDateTime.parse(datetime, DateTimeFormatter.ofPattern(format));
  }

  public static LocalDate toLocalDate(String date, String format) {
    return LocalDate.parse(date, DateTimeFormatter.ofPattern(format));
  }

  /**
   * date与今天相隔的天数 如果 date大于今天将返回负数
   * 
   * @param date
   * @return
   */
  public static long days(Date date) {
    LocalDateTime one = LocalDateTime.ofInstant(date.toInstant(), zone);
    long days = LocalDate.now().toEpochDay() - one.toLocalDate().toEpochDay();
    return days;
  }

  /**
   * date1 与 date2相隔的天数 如果 date2小于date1将返回负数
   * 
   * @param date1
   * @param date2
   * @return
   */
  public static long days(Date date1, Date date2) {
    LocalDateTime one = toLocalDateTime(date1);
    LocalDateTime two = toLocalDateTime(date2);
    long days = two.toLocalDate().toEpochDay() - one.toLocalDate().toEpochDay();
    return days;
  }
  
  /**
   * 返回 date2 - date1 相差的秒数
   * @param date1
   * @param date2
   * @return
   */
  public static long seconds(Date date1, Date date2) {
    return (date2.getTime() - date1.getTime()) / 1000;
  }

  /**
   * 两个日期之间相隔 注意年月日
   * 
   * @param date1
   * @param date2
   * @return
   */
  public static Period period(Date date1, Date date2) {
    LocalDateTime one = toLocalDateTime(date1);
    LocalDateTime two = toLocalDateTime(date2);
    Period period = Period.between(one.toLocalDate(), two.toLocalDate());
    return period;
  }

  /**
   * 得到此时到0点的秒数
   * 
   * @return
   */
  public static long getSecondsOfBetweenNowAndZero() {
    LocalDateTime dateTime = LocalDate.now().plusDays(1).atStartOfDay();
    return Duration.between(LocalDateTime.now(), dateTime).getSeconds();
  }
  
  /**
   * 在当前时间增加毫秒 得到新的时间
   * @param millis
   * @return
   */
  public static LocalDateTime plusMillis(long millis) {
    return LocalDateTime.now().plus(millis, ChronoUnit.MILLIS);
  }
  
  /**
   * 得到毫秒数
   * @param time
   * @return
   */
  public static long getMillis(LocalDateTime time) {
    return time.toInstant(ZoneOffset.of("+8")).toEpochMilli();
  }
  
  /**
   * 得到秒数
   * @param time
   * @return
   */
  public static long getSeconds(LocalDateTime time) {
    return time.toEpochSecond(ZoneOffset.of("+8"));
  }
  
  /**
   * 得到 date与现在比 过去的时间，返回结果由unit决定，取值为 SECONDS MINUTES HOURS DAYS YEARS
   * @param date
   * @param unit
   * @return
   */
  public static long pastTimeFormat(Date date, ChronoUnit unit) {
    if(null == date || null == unit) {
      return 0;
    }
    long seconds = (System.currentTimeMillis() - date.getTime()) / 1000;
    long result = 0;
    switch (unit) {
    case SECONDS:
      result = seconds;
      break;
    case MINUTES:
      result = seconds / 60;
      break;
    case HOURS:
      result = seconds / 60 / 60;
      break;
    case DAYS:
      result = seconds / 60 / 60 / 24;
      break;
    case YEARS:
      result = seconds / 60 / 60 / 24 / 365;
      break;
    default:
      break;
    }
    return result;
  }
  
  public static String pastTimeFormat(Date date) {
    if(null == date) {
      return "";
    }
    long seconds = (System.currentTimeMillis() - date.getTime()) / 1000;
    long r = seconds / 60 / 60 / 24 / 365;
    if(r > 0) {
      return r + "年";
    }
    r = seconds / 60 / 60 / 24;
    if(r > 0) {
      return r + "天";
    }
    r = seconds / 60 / 60;
    if(r > 0) {
      return r + "小时";
    }
    r = seconds / 60;
    if(r > 0) {
      return r + "分钟";
    }
    return seconds + "秒";
  }
}
